package 懒汉式;

/**
 * 双重检查锁实现单例模式
 *  因为读模式是线程安全的，所以只对创建对象的方式进行加锁即可
 *
 *  这种方式有可能在多线程的情况下造成null。所以需要加下volatile关键字在静态常量上
 *  暂时不懂为什么会造成这个问题
 */
public class Singleton2 {
    //私有化构造器
    private Singleton2(){}

    //静态常量
    private static volatile Singleton2 instance;

    //对外提供公共方法
    public static Singleton2 getInstance(){
        // 如果instace不等于null，不用进行锁竞争
        if (instance==null){
            synchronized (Singleton2.class){
                // 第二次检查，注意这里的检查是防止两个锁同时竞争，b线程等待a线程执行完后检查下是否为空
                // 如果不检查直接创建对象那么就并不是单例对象，所以需要再检查如果不为空直接返回
                if (instance==null){
                    instance=new Singleton2();
                }
            }
        }
        return instance;
    }
}
